package com.pubinfo.passbook.common.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;

import java.io.IOException;
import java.io.InputStream;

/**
 * 通过FTP上传文件
 *
 * @Author lvhaibao
 * @Date 2018/2/11 21:43
 */
@Slf4j
public class FtpTool {
  
  public static void uploadDirectory(String workingPath, FTPClient ftpClient) {
    String[] directorys = workingPath.split("/");
    for (String directory : directorys) {
      try {
        if (!ftpClient.changeWorkingDirectory(directory)) {
          ftpClient.makeDirectory(directory);
          ftpClient.changeWorkingDirectory(directory);
        }
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
  }
  
  //设置私有不能实例化
  private FtpTool() {
  }
  
  /**
   * 上传
   *
   * @param hostname    ip或域名地址
   * @param port        端口
   * @param username    用户名
   * @param password    密码
   * @param workingPath 服务器的工作目
   * @param inputStream 要上传文件的输入流
   * @param saveName    设置上传之后的文件名
   * @return
   */
  public static boolean upload(String hostname, int port, String username, String password, String workingPath, InputStream inputStream, String saveName) throws IOException {
    boolean flag = false;
    FTPClient ftpClient = new FTPClient();
    ftpClient.setConnectTimeout(10 * 1000); // 10s，如果超过就判定超时了
    ftpClient.enterLocalPassiveMode();//设置被动模式，文件传输端口设置
    //1 测试连接
    if (connect(ftpClient, hostname, port, username, password)) {
      // 2 检查上传路径，没有的文件夹新建
      uploadDirectory(workingPath, ftpClient);
      ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
      // 3 检查是否上传成功
      if (storeFile(ftpClient, saveName, inputStream)) {
        flag = true;
        disconnect(ftpClient);
      }
    }
    return flag;
  }
  
  /**
   * 断开连接
   *
   * @param ftpClient
   * @throws Exception
   */
  public static void disconnect(FTPClient ftpClient) {
    if (ftpClient.isConnected()) {
      try {
        ftpClient.disconnect();
        log.info("已关闭连接");
      } catch (IOException e) {
        log.info("没有关闭连接");
        e.printStackTrace();
      }
    }
  }
  
  /**
   * 测试是否能连接
   *
   * @param ftpClient
   * @param hostname  ip或域名地址
   * @param port      端口
   * @param username  用户名
   * @param password  密码
   * @return 返回真则能连接
   */
  public static boolean connect(FTPClient ftpClient, String hostname, int port, String username, String password) {
    boolean flag = false;
    try {
      //ftp初始化的一些参数
      ftpClient.connect(hostname, port);
      ftpClient.enterLocalPassiveMode();
      ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
      ftpClient.setControlEncoding("UTF-8");
      if (ftpClient.login(username, password)) {
        log.info("连接ftp成功");
        flag = true;
      } else {
        log.info("连接ftp失败，可能用户名或密码错误");
        try {
          disconnect(ftpClient);
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
    } catch (IOException e) {
      log.info("连接失败，可能ip或端口错误");
      e.printStackTrace();
    }
    return flag;
  }
  
  /**
   * 上传文件
   *
   * @param ftpClient
   * @param saveName        全路径。如/home/public/a.txt
   * @param fileInputStream 要上传的文件流
   * @return
   */
  public static boolean storeFile(FTPClient ftpClient, String saveName, InputStream fileInputStream) {
    boolean flag = false;
    try {
      if (ftpClient.storeFile(saveName, fileInputStream)) {
        flag = true;
        log.info("上传成功");
        disconnect(ftpClient);
      }
    } catch (IOException e) {
      log.info("上传失败");
      disconnect(ftpClient);
      e.printStackTrace();
    }
    return flag;
  }
}